#pragma once

template <class TD> class CogArithmeticProcessor;
class CogLogicalProcessor;

#include "CogEvaluator.h"

#pragma warning( disable : 4250 ) // diamond inheritance dominance

// ------------------------------------------------------------------------------------------

// arithmetic ops
#define OP_ADD		10
#define OP_SUB		11
#define OP_MUL		12
#define OP_DIV		13
#define OP_NEG		20

// logical ops
#define OP_AND		30
#define OP_OR		31
#define OP_NAND		32
#define OP_NOR		33
#define OP_XOR		34
#define OP_NOT		40
#define OP_IF		50

// ------------------------------------------------------------------------------------------

template <class TD>
class CogArithmeticProcessor : public CogSampledEvaluator<TD, CogStackData<TD>>, public CogStackProcessor<TD>
{
public:
	CogArithmeticProcessor();
	bool readParameter(size_t opId, const string& value);
	double error(TD value) { return fabs(static_cast<double>(value - target())); }

protected:
	TD processOperator(size_t id, stack<TD>& result);

	size_t maxVariables;
	vector<vector<TD>> variables;
	vector<TD> constants;
	vector<CogParameterizedOp> parameters;
};

// ------------------------------------------------------------------------------------------

class CogLogicalProcessor : public CogSampledEvaluator<bool, CogStackData<bool>>, public CogStackProcessor<bool>
{
public:
	CogLogicalProcessor();

	bool readParameter(size_t opId, const string& value);
	double error(bool value) { return (value == target()) ? 0.0 : 1.0; }

protected:
	bool processOperator(size_t id, stack<bool>& result);

	size_t maxVariables;
	vector<vector<bool>> variables;
	vector<size_t> parameters;
};

// ------------------------------------------------------------------------------------------

